<?php
/**
 * 权限控制器
 *
 * @author zhangguangbin <zhanggb@yisanban.com>
 * @date 2016.02.22
 * @copyright 易三板(www.yisanban.com)
 */
namespace backend\controllers;
use Yii;
use yii\web\Controller;
use yii\filters\AccessControl;
use yii\data\ArrayDataProvider;
use backend\models\user\User;
use yii\data\Pagination;

class RbacController extends Controller
{

    /**
     *
     * 超级管理员id
     */
    private $_admin = [1,71];

    /**
     *
     * @var object
     */
    private $_auth;

    /**
     * 访问控制
     *
     * @return array
     */
    public function behaviors()
    {
        return [
            'access' => [
                'class' => AccessControl::className(),
                'rules' => [
                    [
                        'allow' => true,
                        'roles' => ['@'],
                    ],
                    [
                        'actions' => ['login', 'captcha'],
                        'allow' => true,
                        'roles' => ['?'],
                    ],
                ],
            ],
        ];
    }

    /**
     * 初始化
     *
     * @var void
     */
    public function init()
    {
        if (!$this->_auth)
        {
            $this->_auth = Yii::$app->authManager;
        }
        parent::init();
    }

//    public function beforeAction($action)
//    {
//        //Yii::$app->controller->id
//        $action = Yii::$app->controller->action->id;
//        var_dump(Yii::$app->user->can($action));
//        print_r(ucfirst($action));exit;
//        if(\Yii::$app->user->can($action)){
//            return true;
//        }else{
//            throw new \yii\web\UnauthorizedHttpException('对不起，您现在还没获此操作的权限');
//        }
//    }


	/**
	 * 管理员列表
	 * 
	 * @return string
	 */
	public function actionIndex()
	{
        if (!Yii::$app->user->can('rbac.admin.list')) {
            return $this->render('/site/403');
        }
        $model = new User();
        $request = Yii::$app->request;
        $sort = $request->get('sort');
        $page = $request->get('page');
        $select['groupId'] = 1;
        $data = $model->getList($select, $sort, $page);
        $data['model'] = $model;
        $data['select'] = $select;
        return $this->render('index', $data);
	}

    /**
     * 模块管理列表
     *
     * @return string
     */
    public function actionModule()
    {
        if (!Yii::$app->user->can('rbac.module.list')) {
            return $this->render('/site/403');
        }
        $list = $this->getPermissions();
        $data['dataProvider'] = new ArrayDataProvider([
            'allModels'=> $list,
        ]);
        $data['pagination'] = new Pagination([
            'totalCount'        => count($list),
           // 'defaultPageSize' => 20
        ]);
        return $this->render('module', $data);
    }

    /**
     * 角色管理列表
     *
     * @return string
     */
    public function actionRoles()
    {
        if (!Yii::$app->user->can('rbac.roles.list')) {
            return $this->render('/site/403');
        }
        $userId = Yii::$app->user->id;
        $list = $this->getRoles();
        if(!in_array($userId,$this->_admin)){
                unset($list['superadmin']);
        }
        $data['dataProvider'] = new ArrayDataProvider([
            'allModels'=> $list,
        ]);
        $data['pagination'] = new Pagination([
            'totalCount'        => count($list),
        ]);
        return $this->render('roles', $data);
    }

    /**
     * 添加模块
     *
     * @return string
     */
    public function actionCreateModule()
    {
        if (!Yii::$app->user->can('rbac.module.create')) {
            return $this->render('/site/403');
        }
        if (Yii::$app->request->isPost){
            $post = Yii::$app->request->post();
            $permission = strtolower($post['module']);
            $create = $this->_auth->createPermission($permission);
            $create->description = trim($post['description']);
           if($this->_auth->add($create)){
               $this->redirect('/rbac/module');
           }
        }
        return $this->render('postModule');
    }

    /**
     * 修改模块
     *
     * @return string
     */
    public function actionUpdateModule($name)
    {
        if (!Yii::$app->user->can('rbac.module.update')) {
            return $this->render('/site/403');
        }
        $permission = $this->_auth->getPermission($name);
        if($permission){
            $data = [
                'module' => strtolower($permission->name),
                'description' => $permission->description
            ];
            if (Yii::$app->request->isPost){
                $post = Yii::$app->request->post();
                $update = $this->_auth->getPermission($name);
                $update->name = $permission = strtolower($post['module']);
                $update->description = trim($post['description']);
                if($this->_auth->update($name,$update)){
                    $this->redirect('/rbac/module');
                }
            }
            return $this->render('postModule',['data'=>$data]);
        }else{
            return $this->render('postModule');
        }
    }

    /**
     * 删除模块
     *
     * @return string
     */
    public function actionDeleteModule(){
        if (!Yii::$app->user->can('rbac.module.delete')) {
            return $this->render('/site/403');
        }
        $name = \Yii::$app->request->post("name");
        $remove = $this->_auth->getPermission($name);
        $this->_auth->remove($remove);
        return json_encode(['code'=>200]);
    }

    /**
     * 添加角色
     *
     * @return string
     */
    public function actionCreateRoles()
    {
        if (!Yii::$app->user->can('rbac.roles.create')) {
            return $this->render('/site/403');
        }
        if (Yii::$app->request->isPost)
        {
            $post = Yii::$app->request->post();
            $name = strtolower($post['name']);
            $role = $this->_auth->createRole($name);
            $role->description = trim($post['description']);
            if($this->_auth->add($role))
            {
                $this->redirect('/rbac/roles');
            }
        }
        return $this->render('postRoles');
    }

    /**
     * 修改角色
     *
     * @return string
     */
    public function actionUpdateRoles($name)
    {
        if (!Yii::$app->user->can('rbac.roles.update')) {
            return $this->render('/site/403');
        }
        $role = $this->_auth->getRole($name);
        if($role){
                $data = [
                    'name' => $role->name,
                    'description' => $role->description
                ];
            if (Yii::$app->request->isPost){
                $post = Yii::$app->request->post();
                $update = $this->_auth->getRole($name);
                $update->name = strtolower($post['name']);
                $update->description = trim($post['description']);
                if($this->_auth->update($name,$update)){
                    $this->redirect('/rbac/roles');
                }
            }
            return $this->render('postRoles',['data'=>$data]);
        }
    }

    /**
     * 删除角色
     *
     * @return string
     */
    public function actionDeleteRoles(){
        if (!Yii::$app->user->can('rbac.roles.delete')) {
            return $this->render('/site/403');
        }
        $name = \Yii::$app->request->post("name");
        $remove = $this->_auth->getRole($name);
        $this->_auth->remove($remove);
        return json_encode(['code'=>200]);
    }

    /**
     * 为用户添加角色
     *
     * @return string
     */
    public function actionAssignRole($userId)
    {
        if (!Yii::$app->user->can('rbac.admin.role')) {
            return $this->render('/site/403');
        }
        $rolesByUser = $this->_auth->getRolesByUser($userId);
        $rolesName = $rolesByUser ? reset($rolesByUser)->name : '';
        $list = $this->getRoles();
        $myUserId = Yii::$app->user->id;
        if(!in_array($myUserId,$this->_admin)){
            unset($list['superadmin']);
        }
        if (Yii::$app->request->isPost){
            $post = Yii::$app->request->post();
            $name = $post['name'];
            $this->_auth->revokeAll($userId);
            $role = $this->_auth->createRole($name);
            $this->_auth->assign($role, $userId);
            $this->redirect('/rbac');
        }
        $data = ['userId'=>$userId,'rolesName'=>$rolesName];
        return $this->render('createAssign',['data'=>$data,'list'=>$list]);
    }

    /**
     * 为角色赋予权限
     *
     * @return string
     */
    public function actionCreateRolesModule($roleName)
    {
        if (!Yii::$app->user->can('rbac.roles.module')) {
            return $this->render('/site/403');
        }
        $default = '';
        $role = $this->_auth->getRole($roleName);
        $list  = $this->getPermissions(true,'name',$roleName);
        foreach($list as $k=>$v){
            $default .= $v['id'].',';
        }
        if (Yii::$app->request->isPost)
        {
            $post = Yii::$app->request->post();
            $permissions = isset($post['permission']) ? $post['permission'] : '' ;
            $allPermissions = $this->getPermissions(false,'id');
            $this->_auth->removeChildren($role);
            $role = $this->_auth->createRole($roleName);
            if($permissions){
                $permissions = explode(',',trim($permissions,','));
                foreach($permissions as $k=>$v){
                    $permission = $this->_auth->createPermission($allPermissions[$v]['name']);
                    $this->_auth->addChild($role, $permission);
                }
            }
            $this->redirect('/rbac/roles');
        }
        return $this->render('createRolesModule',['description'=>$role->description,'list'=>json_encode($list),'default' => trim($default,',')]);
    }

    /**
     * 获取所有模块
     *
     * @param bool $tree 是否返回前端js树形结构
     * @param string $key 返回key值的类型,name:key为name,id:key为id
     * @param string $roleName 角色名
     *
     * @return array || string
     */
    private function getPermissions($tree = false,$key = 'name',$roleName = '')
    {
        $permission  = $this->_auth->getPermissions();
        $list = [];
        if($permission){
            $i = 1;
            foreach($permission as $k=>$v){
                if($key == 'name')
                {
                    $list[$k]['id'] = $i;
                    $list[$k]['name'] = $v->name;
                    $list[$k]['description'] = $v->description;
                    $list[$k]['type'] = $v->type;
                }
                if($key == 'id')
                {
                    $list[$i]['id'] = $i;
                    $list[$i]['name'] = $v->name;
                    $list[$i]['description'] = $v->description;
                    $list[$i]['type'] = $v->type;
                }
                $i++;
            }
        }
        if($tree && $key == 'name')
        {
            $list = $this->getPermissionsTree($list,$roleName);
        }
        return $list;
    }

    /**
     * 获取所有模块转为前端js用的json结构
     *
     * @return string
     */
    private function getPermissionsTree($permission,$roleName)
    {
        $list = $hasRole = [];
        $i = $id = $pid = 0;
        if($roleName){
            $children = $this->_auth->getChildren($roleName);
            foreach($children as $key => $value){
                $hasRole[] = $value->name;
            }
        }
        foreach($permission as $k=>$v){
            $count = substr_count($v['name'],'.');
            $id = $v['id'];
            $name = $v['description'];
            switch ($count)
            {
                case 1:
                    $parent = $permission[substr($v['name'],0,strrpos($v['name'],"."))]['id'];
                    $pid = $parent ? $parent : 0;
                    break;
                case 2:
                    $parent = $permission[substr($v['name'],0,strrpos($v['name'],"."))]['id'];
                    $pid = $parent ? $parent : 0;
                    break;
                case 3:
                    $parent = $permission[substr($v['name'],0,strrpos($v['name'],"."))]['id'];
                    $pid = $parent ? $parent : 0;
                    break;
                default:
                    $pid = 0;
            }
                $list[$i]['id'] = $id;
                $list[$i]['pId'] = $pid;
                $list[$i]['name'] = $name;
                if(in_array($v['name'],$hasRole)){
                    $list[$i]['checked'] = true;
                }
            $i++;
        }
            return $list;
    }

    /**
     * 获取所有角色
     *
     * @return string
     */
    private function getRoles()
    {
        $roles = $this->_auth->getRoles();
        $list = [];
        if($roles){
            foreach($roles as $k=>$v){
                $list[$k]['name'] = $v->name;
                $list[$k]['description'] = $v->description;
                $list[$k]['type'] = $v->type;
            }
        }
        return $list;
    }

}